from threading import Thread, Event
import logging
import time
from gpiozero import DigitalInputDevice

class ProximitySensor(Thread):
    def __init__(self, stop_event, status_queue):
        super().__init__(name="SensorThread")
        self.stop_event = stop_event
        self.status_queue = status_queue
        
        # 引脚定义
        self.UPPER_LIMIT_PIN = 17    # 上限开关 (BCM 17, 物理引脚11)
        self.LOWER_LIMIT_PIN = 27    # 下限开关 (BCM 27, 物理引脚13)
        
        # 创建开关设备对象
        self.upper_limit = DigitalInputDevice(
            self.UPPER_LIMIT_PIN, 
            pull_up=True, 
            bounce_time=0.05  # 50ms去抖
        )
        
        self.lower_limit = DigitalInputDevice(
            self.LOWER_LIMIT_PIN, 
            pull_up=True, 
            bounce_time=0.05
        )
        """GPIO Zero库 提供了底层的事件检测机制：
        库内部使用中断(interrupt)或轮询(polling)方式监测GPIO引脚状态变化
        当检测到状态变化时，自动调用注册的回调函数
        这一切在后台自动运行,不需要在run循环中手动检查
        回调函数在独立的线程中执行，不会阻塞主线程"""
        # 注册状态变化回调
        self.upper_limit.when_activated = lambda: self._upper_limit_reached("UPPER")#队列将接收到一个元组(tuple)("limit_switch", "UPPER")
        self.lower_limit.when_activated = lambda: self._lower_limit_reached("LOWER")
    
    def _upper_limit_reached(self, switch_type):
        """限位开关触发时通知电机暂停"""
        self.status_queue.put(("limit_switch", f"{switch_type}"))
        # print("上限开关触发，电机暂停")

    def _lower_limit_reached(self, switch_type):
        """限位开关触发时通知电机暂停"""
        self.status_queue.put(("limit_switch", f"{switch_type}"))
        # print("下限开关触发，电机暂停")
    
    def run(self):
        logging.info("限位开关线程启动")
        try:
            while not self.stop_event.is_set():
                time.sleep(0.1)
        finally:
            logging.info("限位开关线程安全退出")
            self.upper_limit.close()
            self.lower_limit.close()
